#include "stdafx.h"
#include "system.h"

#include <intrin.h>
#include <time.h>



//__________________________________________________________________________
void init()
{
	srand( (unsigned int)time( NULL ) ); 

	SetThreadAffinityMask( GetCurrentThread(), 1 );
	SetProcessPriorityBoost( GetCurrentProcess(), FALSE );
	SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS );
	SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
	// read on the forums that their weird behaviour with the first calls
	get_cycles();
	get_cycles();
	get_cycles();
	get_cycles();
	get_cycles();
	get_cycles();
	get_cycles();
	get_cycles();
	get_cycles();

	DWORD uiError = GetLastError();
	if ( uiError != 0 )
	{
		printf( "ERROR" );
		/*LPVOID lpMsgBuf;
		formatmessage( 
			format_message_ALLOCATE_BUFFER | format_message_FROM_SYSTEM,
			NULL,
			uiError,
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
			(LPTSTR) &lpMsgBuf,
			0,
			NULL 
		);
		messageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINformatION );
		LocalFree( lpMsgBuf );*/
	}
}

//__________________________________________________________________________
void release()
{
	SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_NORMAL );
	SetPriorityClass( GetCurrentProcess(), NORMAL_PRIORITY_CLASS );
}

//__________________________________________________________________________
#ifdef D_USE_RDTSC
cycles_t get_cycles(void)
{
/*	unsigned long lo, hi;
	__asm
  {
	cpuid
    rdtsc
    mov [lo],eax
    mov [hi],edx
	cpuid
  }

  cycles_t x  = (cycles_t)( ( (__int64)lo)|( ((__int64)hi)<<32 ) );*/

	int dummy[4]; // For unused returns
	volatile int DontSkip; // Volatile to prevent optimizing
	__int64 clock; // Time
	__cpuid(dummy, 0); // Serialize
	DontSkip = dummy[0]; // Prevent optimizing away cpuid
	clock = __rdtsc(); // Read time
	__cpuid(dummy, 0); // Serialize again
	DontSkip = dummy[0]; // Prevent optimizing away cpuid
  return (cycles_t)clock;
}
#endif

#ifdef D_USE_QUERY_PERFORMANCE_COUNTER

cycles_t get_cycles(void)
{
	LARGE_INTEGER liVal;
	liVal.LowPart = 0;
	liVal.HighPart = 0;
	QueryPerformanceCounter( &liVal );
	cycles_t x;
	x  = (double)liVal.HighPart;
	x *= 4294967296.;
	x += (double)liVal.LowPart;
	/*cycles_t x  = (cycles_t)( 
		( (unsigned long)liVal.LowPart ) | ( ((unsigned long)liVal.HighPart)<<32 ) 
		);*/
	return x;
}

#endif
